package drds.plus.sql_process.parser.visitor.dml;

import drds.plus.parser.abstract_syntax_tree.expression.Expression;
import drds.plus.parser.abstract_syntax_tree.expression.Pair;
import drds.plus.parser.abstract_syntax_tree.expression.primary.misc.Identifier;
import drds.plus.parser.abstract_syntax_tree.statement.UpdateStatement;
import drds.plus.parser.abstract_syntax_tree.statement.select.table.ITable;
import drds.plus.parser.visitor.EmptyVisitor;
import drds.plus.sql_process.abstract_syntax_tree.node.dml.Update;
import drds.plus.sql_process.abstract_syntax_tree.node.query.Query;
import drds.plus.sql_process.abstract_syntax_tree.node.query.TableQuery;
import drds.plus.sql_process.parser.visitor.ExpressionVisitor;

import java.util.List;

/**
 * update类型处理
 */
public class UpdateVisitor extends EmptyVisitor {

    private Update updateNode;

    public void visit(UpdateStatement updateStatement) {
        TableQuery tableQueryNode = getTableQueryNode(updateStatement);
        List<Pair<Identifier, Expression>> pairList = updateStatement.getValuePairList();
        StringBuilder updateColumnNamesString = new StringBuilder();
        Object[] updateColumnValues = new Object[pairList.size()];
        for (int i = 0; i < pairList.size(); i++) {
            Pair<Identifier, Expression> pair = pairList.get(i);
            if (i > 0) {
                updateColumnNamesString.append(" ");
            }
            updateColumnNamesString.append(pair.getKey().getText());
            ExpressionVisitor expressionVisitor = new ExpressionVisitor();
            pair.getValue().accept(expressionVisitor);
            updateColumnValues[i] = expressionVisitor.getObject();// 可能为function
        }

        Expression where = updateStatement.getWhere();
        if (where != null) {
            where(tableQueryNode, where);
        }

        this.updateNode = tableQueryNode.update(updateColumnNamesString.toString(), updateColumnValues);
    }

    private TableQuery getTableQueryNode(UpdateStatement updateStatement) {
        ITable table = updateStatement.getTable();
        if (table == null) {
            throw new UnsupportedOperationException("not support more than one where updateNode!");
        }
        ExpressionVisitor tev = new ExpressionVisitor();
        table.accept(tev);
        TableQuery tableQueryNode = (TableQuery) tev.getQuery();
        return tableQueryNode;

    }

    private void where(Query table, Expression expression) {
        ExpressionVisitor expressionVisitor = new ExpressionVisitor();
        expression.accept(expressionVisitor);
        table.setWhereAndSetNeedBuild(expressionVisitor.getFilter());
    }

    public Update getUpdateNode() {
        return updateNode;
    }

}
